#include "CDSF_Control.h"

#include <stdlib.h>
#include "CDSF_Types.h"
#include "CDSF_IO.h"
#include "CDSF_Timer.h"

#define kMaxNumberOfScreens 32

static SFViewController * m_currentRootViewControllers[kMaxNumberOfScreens];


SFViewController * SFControlGetCurrentRootViewController(SFScreenId screenId){
	return m_currentRootViewControllers[screenId];
}

void SFControlSetCurrentRootViewController(SFScreenId screenId, SFViewController *viewController){
	SFViewController *oldViewController = m_currentRootViewControllers[screenId];

	if((oldViewController->viewWillDisappear)!=NULL){
		oldViewController->viewWillDisappear(oldViewController, screenId);
	}
	if((viewController->viewWillAppear)!=NULL){
		viewController->viewWillAppear(viewController, screenId);
	}

	m_currentRootViewControllers[screenId] = viewController;
	SFDisplaySetCurrentRootView(screenId, (viewController->view));
}

SFCode SFControlInit(SFClockRate rate){
	SFScreenId screenId;
	
	if(SFDisplayMaxScreenId>=kMaxNumberOfScreens)
		return SFCodeSpaceFullError;
	
	if(SFControlDefaultRootViewController==NULL)
		return SFCodeConfigurationError;
	
	for(screenId=0; screenId<=SFDisplayMaxScreenId; screenId++){
		m_currentRootViewControllers[screenId] = SFControlDefaultRootViewController;
		SFDisplaySetCurrentRootView(screenId, (SFControlDefaultRootViewController->view));
	}

	return SFIOInit();
}

static int cmp(const void *a, const void *b){
	SFResponseEntry *e1 = (SFResponseEntry *)a;
	SFResponseEntry *e2 = (SFResponseEntry *)b;
	
	return ((e1->keyCode)-(e2->keyCode));
}


SFResponseFunction SFViewControllerGetResponseFunction(const SFViewController *viewController, SFKeyCode keyCode){
	const SFResponseEntryList list = viewController->responseEntryList;
	SFResponseEntry key = {
		.keyCode = keyCode
	};

	SFResponseEntry *result = bsearch(&key, list.entries, list.count, sizeof(SFResponseEntry), cmp); 
	
	if(result==NULL)
		return NULL;
	
	return (result->function);
}


SFCode SFControlDelegate(void){
	SFScreenId screenId;
	SFCode rt;

	SFTimerFire();

	rt = SFIORead();
	if(SFError(rt))
		return rt;

	for(screenId=0; screenId<SFDisplayMaxScreenId; screenId++){
		SFViewController *viewController = SFControlGetCurrentRootViewController(screenId);
		SFKeyCode keyCode;
		const char *inputString;
		SFInputStringMode stringMode;
		
		rt = SFControlReadKey(screenId, &keyCode);
		if(SFOK(rt)){
			SFResponseFunction func = SFViewControllerGetResponseFunction(viewController, keyCode);
			if(func!=NULL){
				func(viewController, screenId, keyCode);
			}
			continue;
		}
		
		rt = SFControlReadInputString(screenId, &inputString, &stringMode);
		if(SFOK(rt)){
			if(viewController->receiveInputString!=NULL){
				viewController->receiveInputString(viewController, screenId, inputString, stringMode);
			}
			continue;
		}
	}

	rt = SFIOWrite();
	if(SFError(rt))
		return rt;

	return SFCodeOK;
}


